package com.sqm.sync_tool;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import cn.hutool.core.date.DateUtil;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.common.utils.AddressUtils;
import com.alibaba.otter.canal.protocol.Message;
import com.alibaba.otter.canal.protocol.CanalEntry.Column;
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqm.sync_tool.entity.*;
import com.sqm.sync_tool.mapper.SysUserMapper;
import com.sqm.sync_tool.utils.PingyinUtil;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@Slf4j
@SpringBootApplication
@MapperScan("com.sqm.sync_tool.mapper")
public class SyncToolApplication {

    @Autowired
    private static SysUserMapper sysUserMapper;

    /**
     * 2.0平台Id
     */
    @Value("${new.infoId}")
    private static String newInfoId;

    /**
     * 1.0 平台Id
     */
    @Value(("${old.infoId}"))
    private static String oldInfoId;


    public static void main(String[] args)  {
        SpringApplication.run(SyncToolApplication.class, args);
        CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("192.168.10.131", 11111), "example", "", "");
        int batchSize = 1000;
        int emptyCount = 0;
        try {
            connector.connect();
            connector.subscribe(".*\\..*");
            connector.rollback();
            int totalEmptyCount = 120;
            while (emptyCount < totalEmptyCount) {
                Message message = connector.getWithoutAck(batchSize); // 获取指定数量的数据
                long batchId = message.getId();
                int size = message.getEntries().size();
                if (batchId == -1 || size == 0) {
                    emptyCount++;
                    System.out.println("empty count : " + emptyCount);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        log.error("e[{}]",e);
                    }
                } else {
                    emptyCount = 0;
                    // System.out.printf("message[batchId=%s,size=%s] \n", batchId, size);
                    printEntry(message.getEntries());
                }

                connector.ack(batchId); // 提交确认
                // connector.rollback(batchId); // 处理失败, 回滚数据
            }

            System.out.println("empty too many times, exit");
        }catch (Exception e){
            log.error("error[{}]",e);
        }finally {
            connector.disconnect();
        }
    }

    private static void printEntry(List<Entry> entrys) {
        for (Entry entry : entrys) {
            if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
                continue;
            }

            RowChange rowChage = null;
            try {
                rowChage = RowChange.parseFrom(entry.getStoreValue());
            } catch (Exception e) {
                throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(),
                        e);
            }

            EventType eventType = rowChage.getEventType();
            System.out.println(String.format("================&gt; binlog[%s:%s] , name[%s,%s] , eventType : %s",
                    entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
                    entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
                    eventType));

            String tableName = entry.getHeader().getTableName();

            for (RowData rowData : rowChage.getRowDatasList()) {
                if (eventType == EventType.DELETE) {
                    printColumn(rowData.getBeforeColumnsList());
                } else if (eventType == EventType.INSERT) {
                    Map<String, String> columnMap = printColumn(rowData.getAfterColumnsList());
                    switch (tableName) {
                        case "sys_user":{
                            //插入用户
                            insertSysUser(columnMap);
                            break;
                        }
                        case "organization":{
                            insertOrganization(columnMap);
                            break;
                        }
                        case "user_organization_relation":{
                            insertUserOrganizationRelation(columnMap);
                            break;
                        }
                        case "user_platform_relation":{
                            insertUserPlatformRelation(columnMap);
                            break;
                        }
                    }
                } else {
                    System.out.println("-------&gt; before");
                    printColumn(rowData.getBeforeColumnsList());
                    System.out.println("-------&gt; after");
                    printColumn(rowData.getAfterColumnsList());
                }
            }
        }
    }

    private static Map<String,String> printColumn(List<Column> columns) {
        HashMap<String, String> columnMap = new HashMap<>();
        for (Column column : columns) {
            columnMap.put(column.getName() , column.getValue());
            System.out.println(column.getName() + " : " + column.getValue() + "    update=" + column.getUpdated());
        }
        return columnMap;
    }

    /**
     * 插入用户信息---
     * @param columnMap
     */
    private  static void insertSysUser( Map<String, String> columnMap){
        SysUser sysUser = new SysUser().setUserId(columnMap.get("user_id"))
                .setUsename(columnMap.get("usename"))
                .setPassword(columnMap.get("password"))
                .setSalt(columnMap.get("salt"))
                .setTelephone(columnMap.get("account"))
                .setStatus(1)
                .setOperationTime(DateUtil.parse(columnMap.get("operation_time"),"yyyy-MM-dd HH:mm:ss"));
        //判断信息是否存在，存在不进行处理-避免重复写入
        String userId = columnMap.get("user_id");
        log.info("userId[{}]",userId);
                SysUser sysUser1 = sysUser.selectById(userId);
        if(sysUser1 == null){
            new HrStaff().setUserId(columnMap.get("user_id"))
                    .setStaffName(columnMap.get("usename"))
                    .setNamePinyin(PingyinUtil.getPinYin(columnMap.get("usename")))
                    .setStaffStatus(6)
                    .setStaffType(0)
                    .setContractStatus(0)
                    .setUpdateTime(DateUtil.parse(columnMap.get("operation_time")).getTime()/1000)
                    .setEntryDate(DateUtil.parse(columnMap.get("operation_time")).getTime()/1000)
                    .setCreateTime(DateUtil.parse(columnMap.get("operation_time")).getTime()/1000)
                    .setMobile(columnMap.get("account"))
                    .setStatus(1)
                    .setInfosId(oldInfoId)
                    .insert();
            sysUser.insert();

        }
    }

    /**
     *插入组织架构
     * @param columnMap
     */
    private static void insertOrganization( Map<String, String> columnMap){
        //判断是否是需要同步的平台
        if (newInfoId.equals(columnMap.get("info_id"))) {
            Organization organization = new Organization().selectById(columnMap.get("organization_chart_id"));
            if(organization == null ){
                QueryWrapper<HrStaff> queryWrapper = new QueryWrapper<HrStaff>().eq("user_id", columnMap.get("master_id"));
                HrStaff hrStaff = new HrStaff().selectOne(queryWrapper);
                new Organization()
                        .setInfoId(oldInfoId)
                        .setOrderNum(Integer.parseInt(columnMap.get("order_num")))
                        .setOrganizationChartId(columnMap.get("organization_chart_id"))
                        .setOrganizationChartName(columnMap.get("organization_chart_name"))
                        .setOrganizationChartPid(columnMap.get("organization_chart_pid"))
                        .setMasterId(columnMap.get("master_id"))
                        .setMasterName(columnMap.get("master_name"))
                        .insert();
                new HrOrganization().setOrganizationId(columnMap.get("organization_chart_id"))
                        .setOrganizationName(columnMap.get("organization_chart_name"))
                        .setOrganizationPid(columnMap.get("organization_chart_pid"))
                        .setMainUserId(hrStaff.getStaffId())
                        .setCreateTime(DateUtil.date().getTime()/1000)
                        .setUpdateTime(DateUtil.date().getTime()/1000)
                        .setInfosId(oldInfoId)
                        .insert();
            }
        }
    }


    /**
     * 插入用户和组织关系
     * @param columnMap
     */
    private static  void  insertUserOrganizationRelation(Map<String, String> columnMap){
        //判断是否是需要同步的平台
        if (newInfoId.equals(columnMap.get("info_id"))) {
            QueryWrapper<UserOrganizationRelation> queryWrapper = new QueryWrapper<UserOrganizationRelation>()
                    .eq("user_id", columnMap.get("user_id"))
                    .eq("organization_chart_id", columnMap.get("organization_chart_id"));
            UserOrganizationRelation userOrganizationRelation = new UserOrganizationRelation().selectOne(queryWrapper);
            Organization organization = new Organization().selectById(columnMap.get("organization_chart_id"));
            if (userOrganizationRelation == null) {
                new UserOrganizationRelation()
                        .setUserId(columnMap.get("user_id"))
                        .setOrganizationChartId(columnMap.get("organization_chart_id"))
                        .setType(organization.getMasterId().equals(columnMap.get("user_id")) ? 1 : -1)
                        .insert();
                QueryWrapper<HrStaff> query = new QueryWrapper<HrStaff>().eq("user_id", columnMap.get("user_id"));
                new HrStaff().selectOne(query)
                        .setOrganizationId(columnMap.get("organization_chart_id"))
                        .updateById();
            }
        }
    }


    /**
     * 插入用户和平台关系
     * @param columnMap
     */
    public static void insertUserPlatformRelation(Map<String, String> columnMap){
        //判断是否是需要同步的平台
        if (newInfoId.equals(columnMap.get("info_id"))) {
            QueryWrapper<UserPlatformRelation> queryWrapper = new QueryWrapper<UserPlatformRelation>()
                    .eq("user_id", columnMap.get("user_id"))
                    .eq("platform_info_id", columnMap.get("platform_info_id"));
            UserPlatformRelation userPlatformRelation = new UserPlatformRelation().selectOne(queryWrapper);
            if (userPlatformRelation == null) {
                new UserPlatformRelation().setUserId(columnMap.get("user_id"))
                        .setPlatformInfoId(oldInfoId)
                        .setStatus(Integer.parseInt(columnMap.get("status")))
                        .insert();
            }
        }
    }
}
